package com.xhsj.user.hr.system.service;

import com.xhsj.user.hr.base.BaseParam;
import com.xhsj.user.hr.process.dto.processDefinition.HandleAuditDto;
import com.xhsj.user.hr.process.hrLeaveProcess.mapper.TbHrApprovalLeaveApplyMapper;
import com.xhsj.user.hr.process.message.service.TbProjectMessageService;
import com.xhsj.user.hr.process.processDefinition.mapper.TbGlobalBusinessMapper;
import com.xhsj.user.hr.process.processDefinition.query.MapQuery;
import com.xhsj.user.hr.process.processDefinition.query.ProcessNodeQuery;
import com.xhsj.user.hr.process.processDefinition.service.TbGlobalApprovalTaskService;
import com.xhsj.user.hr.process.query.ApprovalQuery;
import com.xhsj.user.hr.system.entity.TbGlobalOrganization;
import com.xhsj.user.hr.system.entity.TbGlobalOrganizationApply;
import com.xhsj.user.hr.system.entity.TbHrZhaopinDemandApplyPosition;
import com.xhsj.user.hr.system.mapper.TbGlobalOrganizationMapper;
import com.xhsj.user.hr.system.mapper.TbHrZhaopinDemandApplyPositionMapper;
import com.xhsj.user.hr.system.query.FindDemandApplyAllDataQuery;
import com.xhsj.user.security.entity.LoginUser;
import com.xhsj.user.hr.system.entity.TbHrZhaopinDemandApply;
import com.xhsj.user.hr.system.mapper.TbGlobalUserMapper;
import com.xhsj.user.hr.system.mapper.TbHrZhaopinDemandApplyMapper;
import com.xhsj.user.hr.system.service.TbHrZhaopinDemandApplyService;
import com.xhsj.user.hr.base.BaseService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xhsj.user.hr.system.vo.ZhaopinDemandApplyAuditTaskVo;
import com.xhsj.user.utils.MessageConstant;
import com.xhsj.user.utils.StringUtils;
import com.xhsj.user.utils.UserUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.io.Serializable;
import java.util.concurrent.CompletableFuture;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;

/**
 * <p>
 * 招聘需求申请表 服务实现类
 * </p>
 *
 * @author suxiaolin
 * @since Sep 3, 2020 4:18:20 PM
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbHrZhaopinDemandApply")
public class TbHrZhaopinDemandApplyService extends BaseService<TbHrZhaopinDemandApplyMapper, TbHrZhaopinDemandApply> {
    @Autowired
    private TbHrZhaopinDemandApplyMapper dao;

    @Autowired
    private TbGlobalApprovalTaskService tbGlobalApprovalTaskService;

    @Autowired
    private TbGlobalBusinessMapper tbGlobalBusinessMapper;

    @Autowired
    private TbGlobalUserMapper tbGlobalUserMapper;

    @Autowired
    private TbProjectMessageService tbProjectMessageService;

    @Autowired
    private TbGlobalOrganizationMapper tbGlobalOrganizationMapper;

    @Autowired
    private TbHrZhaopinDemandApplyPositionMapper tbHrZhaopinDemandApplyPositionMapper;

    @Autowired
    private TbGlobalRoleService tbGlobalRoleService;

    @Autowired
    private TbGlobalOrganizationService tbGlobalOrganizationService;

    @Autowired
    private TbHrApprovalLeaveApplyMapper tbHrApprovalLeaveApplyMapper;

    /**
     * 保存
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    //@CacheEvict(cacheNames="TbHrZhaopinDemandApply", allEntries=true)
    public boolean saveData(TbHrZhaopinDemandApply entity) throws Exception {
        entity.setApplyTime(new Date());

        boolean save = super.save(entity);

        Long positionId = entity.getPositionId();
        QueryWrapper<TbGlobalOrganization> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", positionId);
        queryWrapper.eq("type", 1);
        tbHrZhaopinDemandApplyPositionMapper.deleteById(entity.getId());

        Integer integer = tbGlobalOrganizationMapper.selectCount(queryWrapper);
        if (integer == 0) { // 保存新增职位中间表
            TbHrZhaopinDemandApplyPosition applyPosition = new TbHrZhaopinDemandApplyPosition();
            applyPosition.setPositionId(positionId);
            applyPosition.setDepartmentId(entity.getDepartmentId());
            applyPosition.setId(entity.getId());
            applyPosition.setName(entity.getPositionName());
            tbHrZhaopinDemandApplyPositionMapper.save(applyPosition);
        }

        if (save && entity.getSubmitStatus() == 1) { // 提交
            this.startProcess(entity);
        }
        return true;
    }

    /**
     * 重新提交
     *
     * @author 苏小林
     * @date 2020/9/7 14:06
     * @param: data
     */
    public void resubmit(TbHrZhaopinDemandApply data) throws Exception {
        Long processTaskId = data.getProcessTaskId();
        tbGlobalApprovalTaskService.delById(processTaskId);

        this.saveData(data);
    }

    /**
     * 启动招聘申请流程
     *
     * @author 苏小林
     * @date 2020/9/4 10:40
     * @param: entity
     */
    private void startProcess(TbHrZhaopinDemandApply entity) throws Exception {

        LoginUser loginAppUser = UserUtils.getLoginAppUser();
        Long userId = loginAppUser.getUserId();
        HandleAuditDto handleAuditDto = new HandleAuditDto(entity.getId(), userId, userId, 2);
        // 流程启动
        ProcessNodeQuery processNodeQuery = tbGlobalApprovalTaskService.startHandleAudit(handleAuditDto, entity.getDepartmentId());
        entity.setBusinessId(handleAuditDto.getBusinessId());
        // 修改招聘申请信息
        this.updateInfoById(entity, processNodeQuery);

        // 发送消息
        ApprovalQuery approvalQuery =
                new ApprovalQuery(handleAuditDto.getDataId(),
                        MessageConstant.MSG_3, processNodeQuery.getUserId(),
                        processNodeQuery.getRoleIds(),
                        4,
                        UserUtils.getLoginAppUser().getUserId(),
                        UserUtils.getLoginAppUser().getFullName());
        this.sendMessage(approvalQuery);


    }

    /**
     * 修改招聘申请审核相关信息
     *
     * @author 苏小林
     * @date 2020/9/4 11:30
     * @param: entity
     * @param: processNodeQuery
     */
    private void updateInfoById(TbHrZhaopinDemandApply entity, ProcessNodeQuery processNodeQuery) {
        entity.setNodeId(processNodeQuery.getNodeId());
        entity.setNodeName(processNodeQuery.getNodeName());
        entity.setUpdateBy(UserUtils.getLoginAppUser().getUserId());
        entity.setUpdateDate(new Date());
        this.updateById(entity);
    }

    /**
     * 通过id获取数据
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    @Override
    //@Cacheable(key = "#id",sync = true)
    public TbHrZhaopinDemandApply getById(Serializable id) {

        QueryWrapper<TbHrZhaopinDemandApplyPosition> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        TbHrZhaopinDemandApply byId = super.getById(id);
        Integer integer = tbHrZhaopinDemandApplyPositionMapper.selectCount(queryWrapper);
        if (integer > 0) {
            byId.setNewPosition(true);
        }
        return byId;
    }

    /**
     * 通过id删除数据
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    @Override
    //@CacheEvict(cacheNames="TbHrZhaopinDemandApply", allEntries=true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    /**
     * 批量删除数据
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    //@CacheEvict(cacheNames="SysDict", allEntries=true)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return super.removeByIds(idList);
    }

    /**
     * 分页查询数据
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    //@Cacheable(key = "#data",sync = true)
    public IPage<TbHrZhaopinDemandApply> selectPage(Map<String, Object> data) {
        int currentPage = 1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage = (Integer) data.get("page");
        }
        int pageSize = 20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize = (Integer) data.get("size");
        }

        TbHrZhaopinDemandApply entity = JSON.parseObject(JSON.toJSONString(data), TbHrZhaopinDemandApply.class);
        Page<TbHrZhaopinDemandApply> page = new Page(currentPage, pageSize);
        QueryWrapper<TbHrZhaopinDemandApply> wrapper = new QueryWrapper(entity);
        return super.selectPage(page, wrapper);
    }

    /**
     * 查询所有数据
     *
     * @author suxiaolin
     * @date Sep 3, 2020 4:18:20 PM
     */
    @Override
    //@Cacheable(value = "TbHrZhaopinDemandApply",sync = true)
    public List<TbHrZhaopinDemandApply> selectAll() {
        return super.selectAll();
    }


    /**
     * 查询招聘需求申请待审核任务
     *
     * @author 苏小林
     * @date 2020/9/4 13:36
     * @param: baseParam
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.hr.system.vo.ZhaopinDemandApplyAuditTaskVo>
     */
    public IPage<ZhaopinDemandApplyAuditTaskVo> findZhaopinDemandApplyRunTask(BaseParam data) {
        Page<TbHrZhaopinDemandApply> page = new Page(data.getPage(), data.getSize());

        Long userId = UserUtils.getLoginAppUser().getUserId();
        List<Long> roleIds = tbGlobalUserMapper.getRoleIdsByUserId(userId);
        return dao.findZhaopinDemandApplyRunTask(page, userId, roleIds);
    }

    /**
     * 招聘需求申请流程审核
     *
     * @author 苏小林
     * @date 2020/9/4 16:53
     * @param: handleAuditDto
     */
    public void processAudit(HandleAuditDto handleAuditDto) throws Exception {

        ProcessNodeQuery processNodeQuery = tbGlobalApprovalTaskService.handleAudit(handleAuditDto);
        TbHrZhaopinDemandApply entity = new TbHrZhaopinDemandApply();
        if ("完结".equals(processNodeQuery.getNodeName())) {
            Long dataId = handleAuditDto.getDataId();
            // 招聘申请职位中间表
            TbHrZhaopinDemandApplyPosition tbHrZhaopinDemandApplyPosition = tbHrZhaopinDemandApplyPositionMapper.selectById(dataId);
            if (tbHrZhaopinDemandApplyPosition != null) {
                // 招聘申请
                TbHrZhaopinDemandApply tbHrZhaopinDemandApply = dao.selectById(dataId);
                String name = tbHrZhaopinDemandApplyPosition.getName();

                // 查询组织架构表中是否存在职位，防止招聘需求新建岗位未审核通过而重复使用的情况
                QueryWrapper<TbGlobalOrganization> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("name", name);
                queryWrapper.eq("type", 1);

                TbGlobalOrganization tbGlobalOrganization1 = tbGlobalOrganizationMapper.selectOne(queryWrapper);
                if (tbGlobalOrganization1 == null) {
                    // 保存角色
                    tbGlobalRoleService.saveRoleByName(name);
                    // 保存职位
                    TbGlobalOrganization tbGlobalOrganization = new TbGlobalOrganization();
                    tbGlobalOrganization.setType(1);
                    tbGlobalOrganization.setName(name);
                    tbGlobalOrganization.setParentId(tbHrZhaopinDemandApply.getDepartmentId());
                    tbGlobalOrganization.setDescription(tbHrZhaopinDemandApply.getPositionDescription());
                    tbGlobalOrganization.setIsEnable(0);
                    tbGlobalOrganizationService.save(tbGlobalOrganization);
                    entity.setPositionId(tbGlobalOrganization.getId());

                    // 招聘申请职位中间表 职位id
                    tbHrZhaopinDemandApplyPosition.setPositionId(tbGlobalOrganization.getId());
                    tbHrZhaopinDemandApplyPositionMapper.updateById(tbHrZhaopinDemandApplyPosition);
                } else {
                    // 如果存在，就把当前招聘申请和招聘申请职位临时表中的职位id 修改为存在的职位id
                    tbHrZhaopinDemandApplyPosition.setPositionId(tbGlobalOrganization1.getId());
                    tbHrZhaopinDemandApplyPositionMapper.updateById(tbHrZhaopinDemandApplyPosition);
                    entity.setPositionId(tbGlobalOrganization1.getId());
                }
            }

        }

        entity.setId(handleAuditDto.getDataId());
        entity.setBusinessId(handleAuditDto.getBusinessId());
        // 修改招聘申请信息
        this.updateInfoById(entity, processNodeQuery);

        String fullName = tbHrApprovalLeaveApplyMapper.getFullNameByDataId(handleAuditDto.getDataId(),"tb_hr_zhaopin_demand_apply");

        // 发送消息
        ApprovalQuery approvalQuery =
                new ApprovalQuery(handleAuditDto.getDataId(), MessageConstant.MSG_3, processNodeQuery.getUserId(),
                        processNodeQuery.getRoleIds(), 4, UserUtils.getLoginAppUser().getUserId(),fullName);
        this.sendMessage(approvalQuery);
    }


    public void sendMessage(ApprovalQuery approvalQuery) {
        //保存消息
        CompletableFuture<Void> f = CompletableFuture.runAsync(() -> {
            tbProjectMessageService.sendMessageCommon(approvalQuery);
        });
    }

    /**
     * 查询招聘需求申请历史任务
     *
     * @author 苏小林
     * @date 2020/9/4 17:44
     * @param: baseParam
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.hr.system.vo.ZhaopinDemandApplyAuditTaskVo>
     */
    public IPage<ZhaopinDemandApplyAuditTaskVo> findZhaopinDemandApplyHiTask(BaseParam data) {
        Page<TbHrZhaopinDemandApply> page = new Page(data.getPage(), data.getSize());

        Long userId = UserUtils.getLoginAppUser().getUserId();
        return dao.findZhaopinDemandApplyHiTask(page, userId);
    }

    /**
     * 分页查询数据
     *
     * @author 苏小林
     * @date 2020/9/7 11:13
     * @param: data
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.hr.system.entity.TbHrZhaopinDemandApply>
     */
    public IPage<TbHrZhaopinDemandApply> findDemandApplyList(BaseParam data) {
        Page<TbHrZhaopinDemandApply> page = new Page(data.getPage(), data.getSize());
        Long userId = UserUtils.getLoginAppUser().getUserId();
        return dao.findDemandApplyList(page, userId);
    }

    public IPage<TbHrZhaopinDemandApply> findAllData(FindDemandApplyAllDataQuery data) {
        Page<TbHrZhaopinDemandApply> page = new Page(data.getPage(), data.getSize());
        return dao.findAllData(page, data);
    }


    public Set<MapQuery> getPositionByDept(Long deptId) {

        // 查询职位列表
        List<MapQuery> list = tbGlobalOrganizationMapper.getPositionByDept(deptId);

        // 查询中间表
        List<MapQuery> list1 = tbHrZhaopinDemandApplyPositionMapper.getPositionByDept(deptId);
        if (list1 != null && list1.size() > 0) {
            list.addAll(list1);
        }

        Set<MapQuery> mapQueries = new HashSet<>(list);


        return mapQueries;
    }


    public void handleInvalid(Long processTaskId, Long dataId, Long businessId) {

        // 删除历史记录
        tbGlobalApprovalTaskService.delHisTask(businessId,dataId);

        // 删除正在执行任务
        tbGlobalApprovalTaskService.delById(processTaskId);

        // 删除申请数据
        dao.delById(dataId);
    }
}
